import React, { useEffect, useState } from 'react';
import {
  Space,
  Card,
  Flex,
  Form,
  Avatar,
  Image,
  Input,
  Cascader,
  Dropdown,
  Button,
  Table,
  Modal,
  Drawer,
  Empty,
  List,
  Tree,
  Typography,
  Splitter,
  Spin,
  message
} from 'antd';
import type { MenuProps } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  BankOutlined,
  DownOutlined,
  ExclamationCircleFilled,
  InfoCircleOutlined,
  UserOutlined
} from '@ant-design/icons';
import columns from '../../components/columns/certificateColumns';
import companyColumns from '../../components/columns/companyColumns';
import certificateDetailColumns from '../../components/columns/certificateDetailColumns';
import hasAuthority from '../../components/hasAuthority';
import { useStore, observer } from '../../store/certificate/storeHook';
import companyImageData from '../../data/companyImageData';
import dingTalkImageData from '../../data/dingTalkImageData';
import feishuImageData from '../../data/feishuImageData';
import neteaseImageData from '../../data/neteaseImageData';
import wechatImageData from '../../data/wechatImageData';
import { appTypes, booleanOptions, getOptionLabel } from '../../data/statusData';
import { trimObject } from '../../utils/dataUtils';

const CertificateList: React.FC = () => {
  const [searchForm] = Form.useForm();
  const [editForm] = Form.useForm();
  const [messageApi, contextHolder] = message.useMessage();
  const [modal, modalContextHolder] = Modal.useModal();

  const [isAddModalOpen, setIsAddModalOpen] = useState<boolean>(false);
  const [isDetailModalOpen, setIsDetailModalOpen] = useState<boolean>(false);
  const [isEditModalOpen, setIsEditModalOpen] = useState<boolean>(false);
  const [isDrawerOpen, setIsDrawerOpen] = useState<boolean>(false);
  const [logo, setLogo] = useState<string>('');
  const [openEditModalFlag, setOpenEditModalFlag] = useState<boolean>(false);
  const [saveFlag, setSaveFlag] = useState<boolean>(false);
  const [testMode, setTestMode] = useState<boolean>(false);
  const [certificateData, setCertificateData] = useState<string>('');

  const store: any = useStore();

  const rowSelection = {
    onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
      store.certificate.selectRecord(selectedRows[0]);
    },
    getCheckboxProps: (record: any) => ({
      name: record.id
    })
  };

  const companyRowSelection = {
    onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
      store.company.selectRecord(selectedRows[0]);
    },
    getCheckboxProps: (record: any) => ({
      name: record.id
    })
  };

  const detailRowSelection = {
    onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
      store.certificate.selectCertificateRecord(selectedRows[0]);
    },
    getCheckboxProps: (record: any) => ({
      name: record.id
    })
  };

  const companyPagination = {
    showSizeChanger: true,
    showQuickJumper: true,
    pageSizeOptions: [10, 20, 30, 40, 50, 100],
    current: store.company.current + 1,
    pageSize: store.company.pageSize,
    total: store.company.total,
    onChange: (page: number, pageSize: number) => {
      store.company.setPageSize(pageSize);
      searchCompanies(page - 1);
    },
    onShowSizeChange: (current: number, size: number) => {
      store.company.setPageSize(size);
      searchCompanies(current - 1);
    }
  };

  const _companyColumns: ColumnsType<any> = companyColumns(booleanOptions, (record: any) => console.log('.'));
  _companyColumns.shift();

  const appTypeItems: MenuProps['items'] = [
    {
      key: 'Netease',
      label: '网易邮箱',
      icon:
        <Image
          alt="Netease"
          src={neteaseImageData}
          preview={false}
          style={{
            width: 16,
            height: 16
          }}
        />
    },
    {
      key: 'Wechat',
      label: '企业微信',
      icon:
        <Image
          alt="Wechat"
          src={wechatImageData}
          preview={false}
          style={{
            width: 16,
            height: 16
          }}
        />
    },
    {
      key: 'DingTalk',
      label: '钉钉',
      icon:
        <Image
          alt="DingTalk"
          src={dingTalkImageData}
          preview={false}
          style={{
            width: 16,
            height: 16
          }}
        />
    },
    {
      key: 'Feishu',
      label: '飞书',
      icon:
        <Image
          alt="Feishu"
          src={feishuImageData}
          preview={false}
          style={{
            width: 16,
            height: 16
          }}
        />
    }
  ];

  const getEditFormItems = () => {
    let node: React.ReactNode = <></>;
    const appType: string = store.certificate.certificateRecord?.appType || '';
    switch (appType) {
      case 'Netease':
        node = <>
          <Form.Item
            name="domain"
            label="域名"
            rules={[
              { required: true, message: '域名不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
          <Form.Item
            name="appId"
            label="应用ID"
            rules={[
              { required: true, message: '应用ID不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
          <Form.Item
            name="authCode"
            label="应用授权码"
            rules={[
              { required: true, message: '应用授权码不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
          <Form.Item
            name="orgOpenId"
            label="企业OpenId"
            rules={[
              { required: true, message: '企业OpenId不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
        </>;
        break;
      case 'Wechat':
        node = <>
          <Form.Item
            name="corpId"
            label="企业ID"
            rules={[
              { required: true, message: '企业ID不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
          <Form.Item
            name="corpSecret"
            label="应用凭证密钥"
            rules={[
              { required: true, message: '应用凭证密钥不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
          <Form.Item
            name="addressBookSecret"
            label="通讯录同步密钥"
            rules={[
              { required: true, message: '通讯录同步密钥不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
        </>;
        break;
      case 'DingTalk':
        node = <>
          <Form.Item
            name="corpId"
            label="企业ID"
            rules={[
              { required: true, message: '企业ID不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
          <Form.Item
            name="appKey"
            label="应用AppKey"
            rules={[
              { required: true, message: '应用AppKey不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
          <Form.Item
            name="appSecret"
            label="应用AppSecret"
            rules={[
              { required: true, message: '应用AppSecret不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
        </>;
        break;
      case 'Feishu':
        node = <>
          <Form.Item
            name="appId"
            label="应用唯一标识"
            rules={[
              { required: true, message: '应用唯一标识不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
          <Form.Item
            name="appSecret"
            label="应用秘钥"
            rules={[
              { required: true, message: '应用秘钥不能为空' }
            ]}
          >
            <Input maxLength={255} />
          </Form.Item>
        </>;
        break;
    }
    return node;
  };

  const handleAppTypeMenuClick: MenuProps['onClick'] = e => {
    let flag: boolean = false;
    store.certificate.record.details.forEach((item: any) => {
      if (item.appType === e.key) {
        flag = true;
      }
    });
    if (flag) {
      messageApi.warning('已存在相同应用类型');
      return;
    }
    const record: any = {
      appType: e.key,
      data: null
    };
    store.certificate.selectCertificateRecord(record);
    editForm.resetFields();
    editForm.setFieldsValue(record);
    setOpenEditModalFlag(true);
    setIsDetailModalOpen(false);
  };

  const appTypeMenuProps: MenuProps = {
    items: appTypeItems,
    onClick: handleAppTypeMenuClick
  };

  const handleModalClose = (modalKey: string) => {
    if (modalKey === 'detail') {
      if (openEditModalFlag) {
        setIsEditModalOpen(true);
        setSaveFlag(false);
      }
    } else if (modalKey === 'edit') {
      setOpenEditModalFlag(false);
      setIsDetailModalOpen(true);
      if (saveFlag) {
        const certificateRecord: any = { ...store.certificate.certificateRecord };
        const record: any = store.certificate.record;
        if (certificateRecord.id) {
          record.details.forEach((item: any) => {
            if (item.id === certificateRecord.id) {
              item.data = certificateRecord.data;
            }
          });
          store.certificate.selectRecord(record);
        } else {
          certificateRecord.id = new Date().getTime() + '';
          record.details.push(certificateRecord);
          store.certificate.selectRecord(record);
        }
        store.certificate.selectCertificateRecord(null);
      }
    }
  };

  const search = () => {
    store.certificate.fetchData();
  };

  const searchCompanies = (pageNumber: number) => {
    const values: any = searchForm.getFieldsValue(true);
    values.keyword = (values.keyword as string || '').trim();
    values.cityId = values.city ? values.city[values.city.length - 1] : '';
    store.company.fetchData(values.keyword, values.cityId, 'true', '', pageNumber);
  };

  const addRecord = () => {
    store.company.fetchData('', '', '', '', 0);
    setIsAddModalOpen(true);
    searchForm.resetFields();
  }

  const editRecord = (record?: any) => {
    store.certificate.selectRecord(record);
    if (record?.id) {
      store.certificate.fetchDetail();
    }
    setLogo(record.company.logo || null);
    setOpenEditModalFlag(false);
    setIsDetailModalOpen(true);
  };

  const deleteRecord = () => {
    if (!store.certificate.record) {
      messageApi.info('请选择要删除的记录');
      return;
    }
    modal.confirm({
      title: '确定删除当前选中的记录吗？',
      icon: <ExclamationCircleFilled />,
      onOk() {
        store.certificate.deleteData().then((res: any) => {
          if (res.success) {
            messageApi.info('删除成功');
            search();
          } else {
            messageApi.error(res.message);
          }
        });
      },
      onCancel() {}
    });
  };

  const addCertificate = (companyId: string) => {
    if (store.certificate.saving) {
      return;
    }
    store.certificate.addData(companyId).then((res: any) => {
      store.certificate.setSaving(false);
      if (res.success) {
        setIsAddModalOpen(false);
        messageApi.info('新增成功');
        search();
      } else {
        messageApi.error(res.message);
      }
    });
  };

  const saveRecord = () => {
    if (store.certificate.saving) {
      return;
    }
    const data = [ ...store.certificate.record.details ];
    store.certificate.saveData(store.certificate.record.id, data).then((res: any) => {
      store.certificate.setSaving(false);
      if (res.success) {
        setIsDetailModalOpen(false);
        messageApi.info('保存成功');
        search();
      } else {
        messageApi.error(res.message);
      }
    });
  };

  const editDetailData = (record: any) => {
    store.certificate.selectCertificateRecord(record);
    editForm.resetFields();
    setOpenEditModalFlag(true);
    setIsDetailModalOpen(false);
  };

  const testCertificate = (values: any) => {
    const _data: string = JSON.stringify(values);
    setCertificateData(_data);
    const data: any = {
      appType: store.certificate.certificateRecord.appType,
      data: _data
    };
    store.certificate.test(data);
    setIsDrawerOpen(true);
  };

  const testUsers = (departmentId: string) => {
    const data: any = {
      appType: store.certificate.certificateRecord.appType,
      data: certificateData
    };
    store.certificate.testUsers(departmentId, data);
  };

  const saveDetailData = (values: any) => {
    let message: string = '';
    editForm.setFieldsValue(trimObject(values));
    for (const key in values) {
      if (!values[key]) {
        message = `数据校验错误，${key}不能为空`;
        break;
      } else if (values[key].indexOf(' ') >= 0) {
        message = `数据校验错误，${key}不能包含空格`;
        break;
      }
    }
    if (message) {
      messageApi.warning(message);
      return;
    }
    if (testMode) {
      testCertificate(values);
      return;
    }
    const record: any = { ...store.certificate.certificateRecord };
    record.data = JSON.stringify(values);
    store.certificate.selectCertificateRecord(record);
    setSaveFlag(true);
    setIsEditModalOpen(false);
  };

  useEffect(() => {
    store.certificate.fetchData('', '', 0);
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const forbiddenComponent: React.ReactNode = hasAuthority(store, 'authorized');
  if (forbiddenComponent) {
    return forbiddenComponent;
  }

  return (
    <>
      {contextHolder}
      {modalContextHolder}
      <Space
        direction="vertical"
        size={[0, 16]}
        style={{ width: '100%', padding: 16 }}
      >
        <Card
          size="small"
          title={
            <Space style={{ paddingTop: 8, paddingBottom: 16 }}>
              <Space.Compact block>
                <Button
                  disabled={store.certificate.loading}
                  type="primary"
                  htmlType="button"
                  onClick={() => search()}
                >
                  刷新
                </Button>
              </Space.Compact>
              <Space.Compact block>
                <Button
                  disabled={store.certificate.loading}
                  type="primary"
                  htmlType="button"
                  onClick={() => addRecord()}
                >
                  新增
                </Button>
                <Button
                  disabled={store.certificate.loading}
                  type="primary"
                  htmlType="button"
                  danger
                  onClick={deleteRecord}
                >
                  删除
                </Button>
              </Space.Compact>
            </Space>
          }
          className="no-card-body"
          style={{ paddingTop: 12 }}
        />
        <Table
          columns={columns(editRecord)}
          dataSource={store.certificate.data}
          rowKey="id"
          loading={store.certificate.loading}
          bordered
          scroll={{ x: 'max-content' }}
          rowSelection={{
            type: 'radio',
            selectedRowKeys: store.certificate.record ? [store.certificate.record.id] : [],
            ...rowSelection
          }}
          pagination={false}
        />

        <Modal
          title="新增"
          open={isAddModalOpen}
          maskClosable={false}
          destroyOnHidden
          forceRender
          closable={!store.certificate.saving}
          confirmLoading={store.certificate.saving}
          style={{ minWidth: 320 }}
          onOk={() => {
            if (!store.company.record) {
              messageApi.info('请选择公司');
            } else {
              addCertificate(store.company.record.id);
            }
          }}
          onCancel={() => {
            if (!store.certificate.saving) setIsAddModalOpen(false)
          }}
          footer={(_, { OkBtn, CancelBtn }) => (
            <><OkBtn /><CancelBtn /></>
          )}
        >
          <Spin spinning={store.certificate.saving}>
            <Card
              title="选择公司"
              size="small"
              style={{
                borderBottomLeftRadius: 0,
                borderBottomRightRadius: 0,
                borderBottomStyle: 'none'
              }}
            >
              <Space
                direction="vertical"
                size={5}
                style={{ display: 'flex' }}
              >
                <Form
                  form={searchForm}
                  name="searchForm"
                  autoComplete="off"
                  colon={false}
                  layout="horizontal"
                  disabled={store.company.loading}
                  initialValues={{
                    keyword: '',
                    cityId: '',
                    city: undefined
                  }}
                >
                  <Form.Item
                    name="keyword"
                    label="关键词"
                    labelAlign="left"
                    className="compact label-60"
                  >
                    <Input
                      autoFocus
                      maxLength={32}
                      placeholder="名称"
                      style={{ width: 160 }}
                    />
                  </Form.Item>
                  <Form.Item
                    name="city"
                    label="城市"
                    labelAlign="left"
                    className="compact label-60"
                  >
                    <Cascader
                      options={store.company.cityOptions}
                      showSearch
                      style={{ width: 160 }}
                    />
                  </Form.Item>
                </Form>
                <Flex justify="end">
                  <Button
                    disabled={store.company.loading}
                    type="primary"
                    htmlType="button"
                    onClick={() => searchCompanies(0)}
                  >
                    查询
                  </Button>
                </Flex>
              </Space>
            </Card>
            <Table
              columns={_companyColumns}
              dataSource={store.company.data}
              rowKey="id"
              loading={store.company.loading}
              bordered
              scroll={{ x: 'max-content' }}
              rowSelection={{
                type: 'radio',
                selectedRowKeys: store.company.record ? [store.company.record.id] : [],
                ...companyRowSelection
              }}
              pagination={companyPagination}
              className="no-border-radius"
            />
          </Spin>
        </Modal>

        <Modal
          title="同步凭证"
          open={isDetailModalOpen}
          maskClosable={false}
          destroyOnHidden
          forceRender
          closable={!store.certificate.saving}
          confirmLoading={store.certificate.saving}
          style={{ minWidth: 320 }}
          onOk={() => saveRecord()}
          onCancel={() => {
            if (!store.certificate.saving) setIsDetailModalOpen(false)
          }}
          afterClose={() => handleModalClose('detail')}
          footer={(_, { OkBtn, CancelBtn }) => (
            <><OkBtn /><CancelBtn /></>
          )}
        >
          <Spin spinning={store.certificate.detailLoading || store.certificate.saving}>
            <Space
              direction="vertical"
              size={0}
              style={{ width: '100%' }}
            >
              <Card
                title={
                  <Space
                    direction="horizontal"
                    size={5}
                  >
                    {
                      logo ?
                        <Avatar
                          draggable={false}
                          shape="square"
                          src={
                            <Image
                              src={logo.startsWith('/') ? logo : ('/' + logo)}
                              fallback={companyImageData}
                              preview={false}
                            />
                          }
                          style={{ backgroundColor: '#ffffff' }}
                        /> :
                        <Avatar
                          draggable={false}
                          shape="square"
                          icon={<BankOutlined style={{ color: '#707070', fontSize: 24 }} />}
                          style={{ backgroundColor: '#ffffff' }}
                        />
                    }
                    {store.certificate.record?.companyName}
                  </Space>
                }
                size="small"
                className="no-border-radius no-padding-card-body"
                style={{ marginBottom: 8 }}
              >
                <Table
                  columns={certificateDetailColumns(editDetailData)}
                  dataSource={store.certificate.record?.details || []}
                  rowKey="id"
                  scroll={{ x: 'max-content' }}
                  rowSelection={{
                    type: 'radio',
                    selectedRowKeys: store.certificate.certificateRecord ? [store.certificate.certificateRecord.id] : [],
                    ...detailRowSelection
                  }}
                  pagination={false}
                  className="no-border-radius"
                />
              </Card>
              <Space.Compact block>
                <Dropdown
                  menu={appTypeMenuProps}
                  trigger={['click']}
                >
                    <Button
                      color="primary"
                      variant="outlined"
                      htmlType="button"
                    >
                      <Space size={0}>
                        新增
                        <DownOutlined />
                      </Space>
                    </Button>
                  </Dropdown>
                <Button
                  color="danger"
                  variant="outlined"
                  htmlType="button"
                  onClick={() => {
                    if (store.certificate.certificateRecord) {
                      store.certificate.deleteDetail();
                    } else {
                      messageApi.warning('请先选择要删除的记录');
                    }
                  }}
                >
                  删除
                </Button>
              </Space.Compact>
            </Space>
          </Spin>
        </Modal>

        <Modal
          title={`应用凭证 - ${getOptionLabel(appTypes, store.certificate.certificateRecord?.appType)}`}
          open={isEditModalOpen}
          maskClosable={false}
          destroyOnHidden
          forceRender
          style={{ minWidth: 320 }}
          onOk={() => {
            setTestMode(false);
            editForm.submit();
          }}
          onCancel={() => setIsEditModalOpen(false)}
          afterClose={() => handleModalClose('edit')}
          afterOpenChange={(open: boolean) => {
            if (open) {
              editForm.setFieldsValue(store.certificate.certificateRecord);
            }
          }}
          footer={(_, { OkBtn, CancelBtn }) => (
            <>
              <Button
                color="default"
                variant="solid"
                onClick={() => {
                  setTestMode(true);
                  editForm.submit();
                }}
              >
                测试
              </Button>
              <OkBtn />
              <CancelBtn />
            </>
          )}
        >
          <>
            <Form
              form={editForm}
              name="editForm"
              autoComplete="off"
              labelCol={{ span: 6 }}
              wrapperCol={{ span: 16 }}
              preserve={false}
              onFinish={saveDetailData}
              onFinishFailed={() => messageApi.warning('数据校验错误')}
            >
              {getEditFormItems()}
            </Form>
            {
              (store.certificate.certificateRecord?.appType || '') === 'Netease' ? null :
                <Typography.Text type="warning">
                  <Space
                    size={5}
                    style={{
                      alignItems: 'start',
                      display: 'flex'
                    }}
                  >
                    <InfoCircleOutlined />
                    <span>请确保在应用后台为应用配置足够的权限<br></br>必要时需将服务器IP配置为企业可信IP：{store.certificate.serverIps}</span>
                  </Space>
                </Typography.Text>
            }
          </>
        </Modal>

        <Drawer
          closable
          destroyOnHidden
          title="测试：公司部门列表"
          placement="right"
          open={isDrawerOpen}
          loading={store.certificate.testing}
          onClose={() => setIsDrawerOpen(false)}
        >
          {
            !store.certificate.testData.length ?
              <Empty description="应用凭证有误" /> :
              <Splitter layout="vertical">
                <Splitter.Panel>
                  <Tree
                    defaultExpandAll={true}
                    treeData={store.certificate.testData}
                    onSelect={selectedKeys => testUsers(selectedKeys[0] + '')}
                  />
                </Splitter.Panel>
                <Splitter.Panel>
                  <Spin spinning={store.certificate.userTesting}>
                    <List
                      itemLayout="horizontal"
                      dataSource={store.certificate.users}
                      renderItem={(item: any, index: number) => (
                        <List.Item>
                          <List.Item.Meta
                            avatar={item.avatar ?
                              <Avatar src={item.avatar} /> :
                              <Avatar icon={<UserOutlined />} />
                            }
                            title={item.name}
                            description={item.title || '...'}
                          />
                        </List.Item>
                      )}
                    />
                  </Spin>
                </Splitter.Panel>
              </Splitter>
          }
        </Drawer>
      </Space>
    </>
  );
};

export default observer(CertificateList);
